Xml Serialization in Java using Simple
So, I have to serialize some code in Java and I have used Simple (a java Xml Serialization library) before for Xml serialization with Android in Java, so I thought I would use it again for a regular java project.
Here is what I have done. Some examples have failed, some have succeed. Here are my results.
Example 1 – Serializing a simple Person object
Attempt 1 – Failed with exception
import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; @Root public class Person { @Element public String FirstName; @Element public String LastName; }
And here is the Run.java with the main method.
import java.io.File; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; public class Run { public static void main(String[] args) throws Exception { Person p = new Person(); Serializer serializer = new Persister(); File file = new File("person.xml"); serializer.write(p, file); } }
Result
An Exception was thrown because FirstName is null. So maybe it cannot handle null values?
Attempt 2 – Succeeded
Lets try be setting the default values to an empty string.
import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; @Root public class Person { @Element public String FirstName = ""; @Element public String LastName = ""; }
It worked. Here is the xml file.
<person> <FirstName> <LastName> </person>
Attempt 3 – Succeeded
Of course if we set the values for FirstName and LastName…
Person p = new Person(); p.FirstName = "Jared"; p.LastName = "Barneck";
…they show in the Xml as well.
<person> <FirstName>Jared</FirstName> <LastName>Barneck</LastName> </person>
Example 2 – Serializing a Person object with getters and setters
Attempt 1 – Succeeded
I changed the member variables to be private and created public getters and setters.
import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; @Root public class Person { @Element private String FirstName = ""; @Element private String LastName = ""; public String getFirstName() { return FirstName; } public void setFirstName(String inFirstName) { FirstName = inFirstName; } public String getLastName() { return LastName; } public void setLastName(String inLastName) { LastName = inLastName; } }
I now use the setters to set the values in the main method.
import java.io.File; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; public class Run { public static void main(String[] args) throws Exception { Person p = new Person(); p.setFirstName("Jared"); p.setLastName("Barneck"); Serializer serializer = new Persister(); File file = new File("person.xml"); serializer.write(p, file); } }
That worked and output the desired Xml.
<person> <FirstName>Jared</FirstName> <LastName>Barneck</LastName> </person>
Example 3 – Using a custom name
What if the name of the member variables were _FirstName and _LastName. We wouldn’t want the underscore “_” to show up in the Xml.
So what do we do? The documentation says to use this line:
@Element(name=”FirstName”)
Attempt 1 – Success
import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; @Root public class Person { @Element(name="FirstName") private String _FirstName = ""; @Element(name="LastName") private String _LastName = ""; public String getFirstName() { return _FirstName; } public void setFirstName(String inFirstName) { _FirstName = inFirstName; } public String getLastName() { return _LastName; } public void setLastName(String inLastName) { _LastName = inLastName; } }
This worked, and the Xml output was unchanged.
Example 3 – Serializing a List
Ok, now we want to serialize a list of Person objects.
Attempt 1 – Failed with exception
I tried to use an ArrayList<Person> and it didn’t work. The person object is the same as in example 2, but I changed the main method as follows:
import java.io.File; import java.util.ArrayList; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; public class Run { public static void main(String[] args) throws Exception { ArrayList<Person> people = new ArrayList<Person>(); Person p1 = new Person(); p1.setFirstName("Jared"); p1.setLastName("Barneck"); people.add(p1); Person p2 = new Person(); p2.setFirstName("Mike"); p2.setLastName("Michaels"); people.add(p2); Serializer serializer = new Persister(); File file = new File("people.xml"); serializer.write(people, file); } }
So that didn’t work.
Attempt 2 – Failed, no exception, just bad Xml
I created a People class that extends ArrayList<Person>.
import java.util.ArrayList; import org.simpleframework.xml.Root; @Root public class People extends ArrayList<Person> { }
I then used this class in the main method.
public static void main(String[] args) throws Exception { People people = new People(); Person p1 = new Person(); p1.setFirstName("Jared"); p1.setLastName("Barneck"); people.add(p1); Person p2 = new Person(); p2.setFirstName("Mike"); p2.setLastName("Michaels"); people.add(p2); Serializer serializer = new Persister(); File file = new File("people.xml"); serializer.write(people, file); }
It didn’t throw and exception but the Xml was basically empty.
<people/>
That isn’t what we want.
Attempt 3 – Succeeded but not quite right
Ok, so how about a container object instead of an extending object. The documentation has an @ElementList attribute that can be used if the class contains a list. So lets use that.
import java.util.ArrayList; import java.util.List; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; @Root public class People { @ElementList List<Person> List = new ArrayList<Person>(); }
The main method changed slightly to accommodate the People class.
public static void main(String[] args) throws Exception { People people = new People(); Person p1 = new Person(); p1.setFirstName("Jared"); p1.setLastName("Barneck"); people.List.add(p1); Person p2 = new Person(); p2.setFirstName("Mike"); p2.setLastName("Michaels"); people.List.add(p2); Serializer serializer = new Persister(); File file = new File("people.xml"); serializer.write(people, file); }
The Xml was created and looks as follows:
<people> <List class="java.util.ArrayList"> <person> <FirstName>Jared</FirstName> <LastName>Barneck</LastName> </person> <person> <FirstName>Mike</FirstName> <LastName>Michaels</LastName> </person> </List> </people>
That is almost correct. However, we don’t need to the List line between People and person.
Attempt 4 – Succeeded
Ok, so I read the documentation and it said to use this to remove the useless List Xml element.
@ElementList(inline=true)
So I tried and sure enough, it worked.
<people> <person> <FirstName>Jared</FirstName> <LastName>Barneck</LastName> </person> <person> <FirstName>Mike</FirstName> <LastName>Michaels</LastName> </person> </people>
Ok…lets continue this a bit later in another post.
null element are valid, you just have to specify (required=false), like "@Element(required=false)"
another little trick is that you can use non-void constructor just specifying with variable they use:
@Root
public class OrderManager {
@ElementList
private final List orders;
public OrderManager(@ElementList(name="orders") List orders) {
this.orders = orders;
}
}